home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / OpenDoc Development / Debugging Support / OpenDoc Source Code / Utilities / DocUtils.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  36.0 KB  |  1,248 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        DocUtils.cpp
  3.  
  4.     Contains:    code for useful high level Document/Draft utilities
  5.  
  6.     Owned by:    Tantek Çelik
  7.  
  8.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     
  11. */
  12.  
  13. #ifndef _DOCUTILS_
  14. #include "DocUtils.h"
  15. #endif
  16.  
  17. #ifndef SOM_ODDispatcher_xh
  18. #include "Disptch.xh"
  19. #endif
  20.  
  21. #ifndef _ODUTILS_
  22. #include <ODUtils.h>
  23. #endif
  24.  
  25. #ifndef _EXCEPT_
  26. #include "Except.h"
  27. #endif
  28.  
  29. #ifndef SOM_ODFrame_xh
  30. #include "Frame.xh"
  31. #endif
  32.  
  33. #ifndef _STDTYPIO_
  34. #include "StdTypIO.h"
  35. #endif
  36.  
  37. #ifndef _TEMPOBJ_
  38. #include "TempObj.h"
  39. #endif
  40.  
  41. #ifndef _INFOUTIL_
  42. #include "InfoUtil.h"
  43. #endif
  44.  
  45. #ifndef _BNDNSUTL_
  46. #include "BndNSUtl.h"
  47. #endif
  48.  
  49. #ifndef _STORUTIL_
  50. #include "StorUtil.h"        // for GetFileContainer, code could be inline instead. -TÇ
  51. #endif
  52.  
  53. #ifndef _REFCTCOL_
  54. #include "RefCtCol.h"
  55. #endif
  56.  
  57. #ifndef SOM_ODDispatcher_xh
  58. #include <Disptch.xh>
  59. #endif
  60.  
  61. #ifndef SOM_ODUndo_xh
  62. #include <Undo.xh>
  63. #endif
  64.  
  65. #ifndef SOM_ODInfo_xh
  66. #include <Info.xh>
  67. #endif
  68.  
  69. #ifndef SOM_ODClipboard_xh
  70. #include <Clipbd.xh>
  71. #endif
  72.  
  73. #ifndef SOM_ODLinkManager_xh
  74. #include <LinkMgr.xh>
  75. #endif
  76.  
  77. #ifndef SOM_ODWindowState_xh
  78. #include <WinStat.xh>
  79. #endif
  80.  
  81. #ifndef SOM_ODWindowIterator_xh
  82. #include <WinIter.xh>
  83. #endif
  84.  
  85. #ifndef SOM_ODPart_xh
  86. #include <Part.xh>
  87. #endif
  88.  
  89. #ifndef SOM_ODStorageUnit_xh
  90. #include <StorageU.xh>
  91. #endif
  92.  
  93. #ifndef SOM_ODDraft_xh
  94. #include <Draft.xh>
  95. #endif
  96.  
  97. #ifndef SOM_ODDocument_xh
  98. #include <Document.xh>
  99. #endif
  100.  
  101. #ifndef SOM_ODContainer_xh
  102. #include <ODCtr.xh>
  103. #endif
  104.  
  105. #ifndef _TIME
  106. #include <time.h>
  107. #endif
  108.  
  109. #ifndef SOM_Module_OpenDoc_StdTypes_defined
  110. #include <StdTypes.xh>
  111. #endif
  112.  
  113. #ifndef SOM_Module_OpenDoc_StdProps_defined
  114. #include <StdProps.xh>
  115. #endif
  116.  
  117. #ifndef SOM_ODSession_xh
  118. #include <ODSessn.xh>
  119. #endif
  120.  
  121. #ifndef SOM_ODObjectNameSpace_xh
  122. #include "ObjectNS.xh"
  123. #endif
  124.  
  125. #ifndef SOM_ODNameSpaceManager_xh
  126. #include <NmSpcMg.xh>
  127. #endif
  128.  
  129. #ifndef SOM_ODObjectIterator_xh
  130. #include <ObjctItr.xh>
  131. #endif
  132.  
  133. #ifndef _NMSPCUTL_
  134. #include <NmSpcUtl.h>
  135. #endif
  136.  
  137. #ifndef __TOOLUTILS__
  138. #include <ToolUtils.h>
  139. #endif
  140.  
  141. #ifndef __ICONS__
  142. #include <Icons.h>
  143. #endif
  144.  
  145. #ifndef _ODDEBUG_
  146. #include "ODDebug.h"
  147. #endif
  148.  
  149. //==============================================================================
  150. // Constants
  151. //==============================================================================
  152.  
  153. const ODISOStr        kODRefNumDocument            =    "RefNumDocument";
  154. const ODISOStr        kODDocumentTempDraft        =    "DocumentTempDraft";
  155.  
  156. const  ODPropertyName kODPropUnsavedDocument    =    "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Property:UnsavedDocument";
  157. const  ODPropertyName kODPropTempDocument        =    "+//ISO 9070/ANSI::113722::US::CI LABS::OpenDoc:Property:TempDocument";
  158.  
  159.  
  160. static ODUByte gDUHex[] = "0123456789ABCDEF";
  161.  
  162. /* Constants to specify the file fork GetLocalPaths should match */
  163. enum
  164. {
  165.     kDataFork        = 0,
  166.     kResourceFork    = 1
  167. };
  168.  
  169. //==============================================================================
  170. // Local functions
  171. //==============================================================================
  172.  
  173. ODISOStr    ODCreateISOStrKeyFromULong(ODULong    uLongKey);
  174.  
  175. ODULong        ODGetODULongFromISOStrKey(ODISOStr isoStrKey);
  176.  
  177. void        SyncFileToProperties(Environment* ev, ODSession* session, ODDocument* document);
  178. void        SyncPropertiesToFile(Environment* ev, ODSession* session, ODDocument* document);
  179.  
  180. ODFileRefNum    ODDeduceRefNum(Environment* ev, PlatformFile* file, 
  181.                     ODULong prevRefNumCount, ODSShort* prevRefNums);
  182.                     
  183. //------------------------------------------------------------------------------
  184. // Namespace key utilities
  185. //------------------------------------------------------------------------------
  186.  
  187. ODISOStr    ODCreateISOStrKeyFromULong(ODULong    uLongKey)
  188. {
  189.     ODISOStr ret = (ODISOStr)ODNewPtrClear(sizeof(ODULong)*2 + 1);
  190.     for (ODUByte i = 0; i<sizeof(ODULong); ++i)
  191.     {
  192.         ODUByte b = ((ODUByte*)(&uLongKey))[i];
  193.         ret[i*2] = gDUHex[b / 16];
  194.         ret[i*2 + 1] = gDUHex[b % 16];
  195.     }
  196.     return ret;
  197. }
  198.  
  199.  
  200. ODULong        ODGetODULongFromISOStrKey(ODISOStr isoStrKey)
  201. {
  202.     ODULong ret;
  203.     for (ODUByte i = 0; i<sizeof(ODULong); ++i)
  204.     {
  205.         ODUByte n1 = 0, n2 = 0;
  206.         n1 = isoStrKey[i*2];
  207.         n2 = isoStrKey[i*2+1];
  208.         if (n1>'9') 
  209.             n1=n1-'A'+10;
  210.         else 
  211.             n1=n1-'0';
  212.         if (n2>'9') 
  213.             n2=n2-'A'+10;
  214.         else 
  215.             n2=n2-'0';
  216.         
  217.         ((ODUByte*)(&ret))[i] = n1*16 + n2;
  218.     }
  219.     return ret;
  220. }
  221.  
  222.  
  223. //------------------------------------------------------------------------------
  224. // ODDeduceRefNum
  225. //------------------------------------------------------------------------------
  226.  
  227. ODFileRefNum    ODDeduceRefNum(Environment* ev, PlatformFile* file, 
  228.                     ODULong prevRefNumCount, ODSShort* prevRefNums)
  229. {
  230.     ODFileRefNum    retval = 0;
  231.     ODULong         newRefNumCount = 0;
  232.     ODSShort*         newRefNums = kODNULL;
  233.     file->GetLocalPaths(kDataFork, &newRefNumCount, &newRefNums);
  234.  
  235.     WASSERT(newRefNumCount == prevRefNumCount + 1);
  236.  
  237.     ODULong i = 0,j;
  238.     ODBoolean found = kODFalse;
  239.     
  240.     while  (i<newRefNumCount)
  241.     {
  242.         j = 0;
  243.         while (j<prevRefNumCount && (found = (newRefNums[i] == prevRefNums[j]))==kODFalse)
  244.             ++j;
  245.         if (!found)
  246.             break;
  247.         ++i;
  248.     }
  249.     
  250.     WASSERT(i<newRefNumCount);
  251.     
  252.     retval = newRefNums[i];
  253.     
  254.     if (newRefNums) 
  255.         ODDisposePtr((Ptr)newRefNums);
  256.     
  257.     return retval;
  258. }
  259.  
  260.  
  261.  
  262. //==============================================================================
  263. // Opening an file/container/document/draft
  264. //==============================================================================
  265.  
  266.  
  267. void ODAcquireCtrDocTopDraft(Environment* ev, ODSession* session,PlatformFile* file,
  268.         ODContainer** container, ODDocument** document, ODDraft** draft)
  269. {
  270.     *container = GetFileContainer(ev, session, &(file->GetFileSpec()));
  271.     *document = (*container)->AcquireDocument(ev,kODDefaultDocument);
  272.     *draft = (*document)->AcquireDraft(ev,kODDPReadOnly,0,kODNULL,kODPosTop,kODFalse);
  273. }
  274.  
  275. //------------------------------------------------------------------------------
  276. // ODGetFirstOpenDocument
  277. //------------------------------------------------------------------------------
  278.  
  279. ODDocument*    ODGetFirstOpenDocument(Environment* ev, ODSession* session)
  280. {
  281.     return ODGetNthOpenDocument(ev, session, 1);
  282. }
  283.                 
  284. //------------------------------------------------------------------------------
  285. // ODGetNthOpenDocument
  286. //
  287. // n is 1 based & returns kODNULL if there is no nth document
  288. //------------------------------------------------------------------------------
  289.  
  290. ODDocument*    ODGetNthOpenDocument(Environment* ev, ODSession* session, ODULong n)
  291. {
  292.     WASSERT(session != kODNULL);
  293.     
  294.     if (!session)
  295.         THROW(kODErrIllegalNullInput);
  296.         
  297.     ODNameSpaceManager* theNameSpaceManager = session->GetNameSpaceManager(ev);
  298.     ODObjectNameSpace* refNumDocumentNameSpace = 
  299.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  300.                                                         kODRefNumDocument);
  301.     RETURN_IF_NULL(refNumDocumentNameSpace, kODNULL);
  302.     
  303.     ODObjectIterator* iter = refNumDocumentNameSpace->CreateIterator(ev);
  304.     ODDocument* document = kODNULL;
  305.     ODISOStr unusedKey = kODNULL;
  306.     ODULong unusedObjectLength;
  307.     iter->First(ev, &unusedKey, (ODObject**)&document, &unusedObjectLength);
  308.     while (--n > 0 && document != kODNULL)
  309.     {
  310.         ODDisposePtr(unusedKey);
  311.         unusedKey = kODNULL;
  312.         document = kODNULL;
  313.         iter->Next(ev, &unusedKey, (ODObject**)&document, &unusedObjectLength);
  314.     }
  315.     ODDisposePtr(unusedKey);
  316.     ODDeleteObject(iter);
  317.     return document;
  318. }
  319.                 
  320. //------------------------------------------------------------------------------
  321. // ODGetOpenDocumentFromRefNum
  322. //------------------------------------------------------------------------------
  323.  
  324. ODDocument*    ODGetOpenDocumentFromRefNum(Environment* ev, ODSession* session,
  325.                 ODFileRefNum refnum)
  326. {
  327.     WASSERT(session != kODNULL);
  328.  
  329.     if (!session)
  330.         THROW(kODErrIllegalNullInput);
  331.         
  332.     ODNameSpaceManager* theNameSpaceManager = session->GetNameSpaceManager(ev);
  333.     ODObjectNameSpace* refNumDocumentNameSpace = 
  334.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  335.                                                         kODRefNumDocument);
  336.     RETURN_IF_NULL(refNumDocumentNameSpace, kODNULL);
  337.     ODDocument* document = kODNULL;
  338.     TempODISOStr    key = ODCreateISOStrKeyFromULong(refnum);
  339.     refNumDocumentNameSpace->GetEntry(ev, key, (ODObject**)&document);
  340.     return document;
  341. }
  342.                 
  343. //------------------------------------------------------------------------------
  344. // ODGetTempDraftFromOpenDocument
  345. //------------------------------------------------------------------------------
  346.                 
  347. ODDraft*    ODGetTempDraftFromOpenDocument(Environment* ev, ODSession* session,
  348.                 ODDocument* document)
  349. {
  350.     RETURN_IF_NULL(document, kODNULL);
  351.  
  352.     WASSERT(session != kODNULL);
  353.     if (!session)
  354.         THROW(kODErrIllegalNullInput);
  355.         
  356.     ODNameSpaceManager* theNameSpaceManager = session->GetNameSpaceManager(ev);
  357.  
  358.     ODObjectNameSpace* documentTempDraftNameSpace = 
  359.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  360.                                                         kODDocumentTempDraft);
  361.     RETURN_IF_NULL(documentTempDraftNameSpace, kODNULL);
  362.     ODDraft* draft = kODNULL;
  363.     TempODISOStr    key = ODCreateISOStrKeyFromULong((ODULong)document);
  364.     documentTempDraftNameSpace->GetEntry(ev, key, (ODObject**)&draft);
  365.     return draft;
  366. }
  367.  
  368. //------------------------------------------------------------------------------
  369. // ODTempDraftCreated
  370. //------------------------------------------------------------------------------
  371.                 
  372. void    ODTempDraftCreated(Environment* ev, ODSession* session, 
  373.             ODDocument* document, ODDraft* tempDraft)
  374. {
  375.     WASSERT(session != kODNULL);
  376.     WASSERT(document != kODNULL);
  377.     WASSERT(tempDraft != kODNULL);
  378.  
  379.     if (!session)
  380.         THROW(kODErrIllegalNullInput);
  381.     if (!document)
  382.         THROW(kODErrIllegalNullDocumentInput);
  383.     if (!tempDraft)
  384.         THROW(kODErrIllegalNullDraftInput);
  385.         
  386.     ODNameSpaceManager* theNameSpaceManager = session->GetNameSpaceManager(ev);
  387.  
  388.     ODObjectNameSpace* nameSpace =    
  389.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  390.                                                         kODDocumentTempDraft);
  391.     if (!nameSpace)
  392.     {
  393.         nameSpace = 
  394.             (ODObjectNameSpace*)theNameSpaceManager->CreateNameSpace(
  395.                 ev, kODDocumentTempDraft, kODNULL, 5, kODNSDataTypeODObject);
  396.     }
  397.     
  398.     {
  399.         TempODISOStr key = ODCreateISOStrKeyFromULong((ODULong)document);
  400.         ODDraft* unusedDraft;
  401.         if (nameSpace->GetEntry(ev, key, (ODObject**)&unusedDraft))
  402.             nameSpace->Unregister(ev, key);
  403.         nameSpace->Register(ev, key, tempDraft);
  404.     }
  405. }
  406.  
  407. //------------------------------------------------------------------------------
  408. // ODDocumentOpened
  409. //------------------------------------------------------------------------------
  410.                 
  411. void        ODDocumentOpened(Environment* ev, ODSession* session,
  412.                 ODFileRefNum refnum, ODDocument* document, ODDraft* tempDraft)
  413. {
  414.     WASSERT(session != kODNULL);
  415.     WASSERT(document != kODNULL);
  416.  
  417.     if (!session)
  418.         THROW(kODErrIllegalNullInput);
  419.     if (!document)
  420.         THROW(kODErrIllegalNullDocumentInput);
  421.         
  422.     ODNameSpaceManager* theNameSpaceManager = session->GetNameSpaceManager(ev);
  423.  
  424.     document->Acquire(ev);    // Balanced by Release in ODDocumentClosed.
  425.     document->GetContainer(ev)->Acquire(ev); // Balanced by Release in ODDocumentClosed.
  426.  
  427.     //• it's not clear whether ODDocumentClosed needs to be called if this fn fails.
  428.     //• Failure halfway through leaves things in an inconsistent state and it doesn't
  429.     //• look like there's any way to clean up fully.
  430.  
  431.     ODObjectNameSpace* nameSpace = 
  432.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  433.                                                         kODRefNumDocument);
  434.     if (!nameSpace)
  435.     {
  436.         nameSpace = 
  437.             (ODObjectNameSpace*)theNameSpaceManager->CreateNameSpace(
  438.                 ev, kODRefNumDocument, kODNULL, 5, kODNSDataTypeODObject);
  439.     }
  440.     
  441.     {
  442.         TempODISOStr key = ODCreateISOStrKeyFromULong((ODULong)refnum);
  443. #if ODDebug
  444.         ODDocument* unusedDocument;
  445.         if (nameSpace->GetEntry(ev, key, (ODObject**)&unusedDocument))
  446.             WARN("refnum already in kODRefNumDocument namespace!");
  447. #endif
  448.         nameSpace->Register(ev, key, document);
  449.     }
  450.     
  451.     if (tempDraft)
  452.         ODTempDraftCreated(ev, session, document, tempDraft);
  453. }
  454.                 
  455. //------------------------------------------------------------------------------
  456. // ODDocumentClosed
  457. //------------------------------------------------------------------------------
  458.                 
  459. void    ODDocumentClosed(Environment* ev, ODSession* session,
  460.                 ODDocument* document)
  461. {
  462.     WASSERT(session != kODNULL);
  463.     WASSERT(document != kODNULL);
  464.  
  465.     if (!session)
  466.         THROW(kODErrIllegalNullInput);
  467.     if (!document)
  468.         THROW(kODErrIllegalNullDocumentInput);
  469.         
  470.     ODNameSpaceManager* theNameSpaceManager = session->GetNameSpaceManager(ev);
  471.     ODObjectNameSpace* nameSpace;
  472.     
  473.     nameSpace = 
  474.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  475.                                                     kODDocumentTempDraft);
  476.     if (nameSpace)
  477.     {
  478.         TempODISOStr key = ODCreateISOStrKeyFromULong((ODULong)document);
  479.         ODDraft* unusedDraft;
  480.         if (nameSpace->GetEntry(ev, key, (ODObject**)&unusedDraft))
  481.             nameSpace->Unregister(ev, key);
  482.     }
  483.     
  484.     nameSpace = 
  485.         (ODObjectNameSpace*)theNameSpaceManager->HasNameSpace( ev, 
  486.                                                         kODRefNumDocument);
  487.     if (!nameSpace)
  488.         return;
  489.  
  490.     ODDocument* entryDocument = kODNULL;
  491.     ODISOStr key = kODNULL;
  492.     ODULong unusedObjectLength;
  493.     ODObjectIterator* iter = nameSpace->CreateIterator(ev);
  494.     for (iter->First(ev, &key, (ODObject**)&entryDocument, &unusedObjectLength);
  495.          iter->IsNotComplete(ev);
  496.          iter->Next(ev, &key, (ODObject**)&entryDocument, &unusedObjectLength))
  497.     {
  498.         TempODISOStr tempKey = key; // DMc: ensure it's deleted
  499.         if (ODObjectsAreEqual(ev, document, entryDocument))
  500.         {
  501.             nameSpace->Unregister(ev, key);
  502.             ODContainer* container = document->GetContainer(ev);
  503.             ODFinalReleaseObject(ev, document);
  504.             ODFinalReleaseObject(ev, container);
  505.             break;
  506.         }
  507.     }
  508.     ODDeleteObject(iter);
  509. }
  510.  
  511.  
  512. //==============================================================================
  513. // Root Part/StorageUnit
  514. //==============================================================================
  515.  
  516. //------------------------------------------------------------------------------
  517. // ODAcquireRootPartOfDraft
  518. //------------------------------------------------------------------------------
  519.  
  520. ODPart* ODAcquireRootPartOfDraft(Environment* ev, ODDraft* draft)
  521. {
  522.     if (!draft)
  523.         THROW(kODErrIllegalNullDraftInput);
  524.         
  525.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  526.     return draft->
  527.         AcquirePart(ev,ODGetStrongSURefProp(ev, su, kODPropRootPartSU, kODStrongStorageUnitRef));
  528. }
  529.  
  530. //------------------------------------------------------------------------------
  531. // ODAcquireRootPartSUOfDraft
  532. //------------------------------------------------------------------------------
  533.  
  534. ODStorageUnit* ODAcquireRootPartSUOfDraft(Environment* ev, ODDraft* draft)
  535. {
  536.     if (!draft)
  537.         THROW(kODErrIllegalNullDraftInput);
  538.         
  539.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  540.     if (!su->Exists(ev, kODPropRootPartSU, kODStrongStorageUnitRef, 0))
  541.         return kODNULL;
  542.         
  543.     return draft->
  544.         AcquireStorageUnit(ev,ODGetStrongSURefProp(ev, su, kODPropRootPartSU, kODStrongStorageUnitRef));
  545. }
  546.  
  547. //------------------------------------------------------------------------------
  548. // ODSetRootPartSUOfDraft
  549. //------------------------------------------------------------------------------
  550.  
  551. void ODSetRootPartSUOfDraft(Environment* ev, ODDraft* draft, ODStorageUnit* rootPartSU)
  552. {
  553.     if (!draft)
  554.         THROW(kODErrIllegalNullDraftInput);
  555.     if (!rootPartSU)
  556.         THROW(kODErrIllegalNullStorageUnitInput);
  557.         
  558.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  559.     ODSetStrongSURefProp(ev, su, kODPropRootPartSU, kODStrongStorageUnitRef,
  560.                         rootPartSU->GetID(ev));
  561. }
  562.  
  563. //------------------------------------------------------------------------------
  564. // ODGetDraftOfWindow
  565. //  Given a window object, get the root part's storageUnit's draft
  566. //------------------------------------------------------------------------------
  567.  
  568. ODDraft* ODGetDraftOfWindow(Environment* ev, ODWindow* window)
  569. {
  570.     RETURN_IF_NULL(window, kODNULL);
  571.         
  572.     TempODPart part = window->GetRootFrame(ev)->AcquirePart(ev);
  573.     return part->GetStorageUnit(ev)->GetDraft(ev);
  574. }
  575.  
  576. //------------------------------------------------------------------------------
  577. // ODResetDateModByInfo
  578. //------------------------------------------------------------------------------
  579.  
  580. void ODResetDateModByInfo(Environment* ev, ODStorageUnit* su)
  581. {
  582.     WASSERT(su != kODNULL);
  583.     if (!su)
  584.         THROW(kODErrIllegalNullStorageUnitInput);
  585.  
  586.     WASSERT(HAS_WRITE_ACCESS(su->GetDraft(ev)->GetPermissions(ev)));
  587.             
  588.     ODTime dateTime;
  589.     time((time_t *)(&dateTime));
  590.     ODSetCreationDate(ev, su, dateTime);
  591.     ODSetModificationDate(ev, su, dateTime);
  592.     
  593.     ODIText        modBy;
  594.     su->GetSession(ev)->GetUserName(ev, &modBy);
  595.     TRY
  596.         ODSetModifiedBy(ev, su, &modBy);
  597.     CATCH_ALL
  598.         DisposeITextStruct(modBy);
  599.         RERAISE;
  600.     ENDTRY
  601.     DisposeITextStruct(modBy);
  602.     
  603.     TempODStorageUnit    rootSU = ODAcquireRootPartSUOfDraft(ev, su->GetDraft(ev));
  604.     if (ODObjectsAreEqual(ev, su, rootSU))
  605.     {
  606.         TempPlatformFile    file = GetPlatformFileFromContainer(ev, 
  607.             su->GetDraft(ev)->GetDocument(ev)->GetContainer(ev));
  608.         TempODName             partname = file->GetName();
  609.         //ODSetPOName(ev, rootPart, partname); // don't want to have to have the part so…
  610.         ODSetITextProp(ev, su, kODPropName, kODMacIText, partname);
  611.     }
  612. }
  613.  
  614. //------------------------------------------------------------------------------
  615. // ODGetDocumentFileName
  616. //------------------------------------------------------------------------------
  617.  
  618. void ODGetDocumentFileName(Environment* ev, ODDocument* document, char* fileName)
  619. {
  620.     TempPlatformFile    file = GetPlatformFileFromContainer(ev, document->GetContainer(ev));
  621.     file->GetAsciiName(fileName, 255);
  622. }
  623.  
  624. //==============================================================================
  625. // Cursor Utils
  626. //==============================================================================
  627.  
  628. void WatchCursor()
  629. {
  630.     SetCursor(*GetCursor(watchCursor));
  631. }
  632.  
  633. void ArrowCursor()
  634. {
  635.     SetCursor(&(ODQDGlobals.arrow));
  636. }
  637.  
  638. //==============================================================================
  639. // Active/Changed Utils
  640. //==============================================================================
  641.  
  642. ODWindow*    ODAcquireActiveWindow(Environment* ev, ODSession* session)
  643. {
  644.     WASSERT(session != kODNULL);
  645.     if (!session)
  646.         THROW(kODErrIllegalNullInput);
  647.         
  648.     return session->GetWindowState(ev)->AcquireActiveWindow(ev);
  649. }
  650.  
  651. ODDraft*    ODGetActiveDraft(Environment* ev, ODSession* session)
  652. {
  653.     TempODWindow window = ODAcquireActiveWindow(ev, session);
  654.     return ODGetDraftOfWindow(ev, window);
  655. }
  656.  
  657. ODDocument*    ODGetActiveDocument(Environment* ev, ODSession* session)
  658. {
  659.     ODDraft* draft = ODGetActiveDraft(ev, session);
  660.     RETURN_IF_NULL(draft, kODNULL);    
  661.     
  662.     return draft->GetDocument(ev);
  663. }
  664.  
  665. ODBoolean    ODDocumentHasChanges(Environment* ev, ODSession* session,
  666.                 ODDocument* document)
  667. {
  668.     ODDraft* draft = ODGetTempDraftFromOpenDocument(ev, session, document);
  669.     RETURN_IF_NULL(draft, kODFalse);    
  670.  
  671.     return draft->ChangedFromPrev(ev);
  672. }
  673.  
  674. ODBoolean    ODDocumentHasWriteAccess(Environment* ev, ODSession* session,
  675.                 ODDocument* document)
  676. {
  677.     return ODDraftHasWriteAccess(ev, ODGetTempDraftFromOpenDocument(ev, session, document));
  678. }
  679.  
  680.  
  681. ODBoolean ODDraftHasWriteAccess(Environment* ev, ODDraft* draft)
  682. {
  683.     RETURN_IF_NULL(draft, kODFalse);    
  684.     
  685.     return HAS_WRITE_ACCESS(draft->GetPermissions(ev));
  686. }
  687.  
  688. //==============================================================================
  689. // User level document operations
  690. //==============================================================================
  691.  
  692. //------------------------------------------------------------------------------
  693. // ODNewDocument
  694. //------------------------------------------------------------------------------
  695.  
  696. #define    kODErrEditorLibraryNotFound                -29816
  697. // error code copied from the Shell (RlShlDef.h)
  698.  
  699. void ODNewDocument(Environment* ev, ODContainer* container,
  700.                             ODType        rootPartKind,
  701.                             ODEditor    rootPartEditor)
  702. {
  703.     TempODDocument    document = container->AcquireDocument(ev, kODDefaultDocument);
  704.     TempODDraft        draft = document->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  705.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  706.  
  707.     ODResetDateModByInfo(ev, su);    
  708.     
  709.   // create new root part
  710.       TempODPart rootPart = kODNULL;
  711.       
  712.       TRY
  713.         rootPart = draft->CreatePart(ev, rootPartKind, rootPartEditor);
  714.     CATCH_ALL
  715.         if (ErrorCode()==fragLibNotFound)
  716.             THROW(kODErrEditorLibraryNotFound);
  717.         else
  718.             RERAISE;
  719.     ENDTRY
  720.     ODStorageUnit* partSU = rootPart->GetStorageUnit(ev);
  721.     if (partSU == kODNULL)
  722.         THROW(kODErrEditorLibraryNotFound);
  723.     ODSetRootPartSUOfDraft(ev, draft, partSU);
  724.  
  725.     ODSetBooleanProp(ev, su, kODPropUnsavedDocument, kODBoolean, kODTrue);
  726.  
  727.     draft->Externalize(ev);
  728.  
  729.     ODPlatformType    rootPartOSType = ODGetIconFilePlatformTypeFromPartSU(ev, partSU);
  730.  
  731.     TempPlatformFile file = GetPlatformFileFromContainer(ev, container);
  732.     file->SetPlatformType(rootPartOSType);
  733. }
  734.  
  735. //------------------------------------------------------------------------------
  736. // ODIsUnsavedNewDocument
  737. //------------------------------------------------------------------------------
  738.  
  739. ODBoolean ODIsUnsavedNewDocument(Environment* ev, ODSession* session, ODDocument* document)
  740. {
  741.     ODDraft* draft = ODGetTempDraftFromOpenDocument(ev, session, document);
  742.     RETURN_IF_NULL(draft, kODFalse);
  743.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  744.     if (!su->Exists(ev, kODPropUnsavedDocument, kODBoolean, 0))
  745.         return kODFalse;
  746.     return ODGetBooleanProp(ev, su, kODPropUnsavedDocument, kODBoolean);
  747. }
  748.  
  749. //------------------------------------------------------------------------------
  750. // ODSetIsUnsavedNewDocument
  751. //------------------------------------------------------------------------------
  752.  
  753. void ODSetIsUnsavedNewDocument(Environment* ev, ODDraft* draft)
  754. {
  755.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  756.     ODSetBooleanProp(ev, su, kODPropUnsavedDocument, kODBoolean, kODTrue);
  757. }
  758.  
  759. //------------------------------------------------------------------------------
  760. // ODOpenFileDocument
  761. //------------------------------------------------------------------------------
  762.  
  763. ODDraft* ODOpenFileDocument(Environment* ev, ODSession* session, PlatformFile* file,
  764.     ODDraftPermissions permissions)
  765. {
  766.     WASSERT(session != kODNULL);
  767.     WASSERT(file != kODNULL);
  768.  
  769.     if (!session)
  770.         THROW(kODErrIllegalNullInput);
  771.     if (!file)
  772.         THROW(kODErrIllegalNullInput);
  773.  
  774.     ODContainer*    container    = kODNULL;
  775.     ODDocument*        document    = kODNULL;
  776.     ODDraft*        currentdraft    = kODNULL;
  777.     ODDraft*        tempdraft    = kODNULL;
  778.     
  779.     ODULong refNumCount, i;
  780.     ODSShort* refNums = kODNULL;
  781.     file->GetLocalPaths(kDataFork, &refNumCount, &refNums);
  782.     
  783.     for ( i=0; i<refNumCount; ++i)
  784.         if ((document = ODGetOpenDocumentFromRefNum(ev, session, refNums[i])) != kODNULL)
  785.         {
  786.             currentdraft = ODGetTempDraftFromOpenDocument(ev, session, document);
  787.             if (currentdraft)
  788.                 currentdraft->Acquire(ev);
  789.             else
  790.                 currentdraft = document->AcquireDraft(ev,kODDPReadOnly,0,kODNULL,kODPosTop,kODFalse);
  791.             if (refNums)
  792.                 ODDisposePtr(refNums);
  793.             return currentdraft;
  794.         }
  795.  
  796.     // ODAcquireCtrDocTopDraft opens the file and adds a new refnum.
  797.  
  798.     ODAcquireCtrDocTopDraft(ev, session, file, &container, &document, ¤tdraft);
  799.     TempODContainer tempCont = container;        // Ensures they're released
  800.     TempODDocument  tempDoc  = document;
  801.     ODFileRefNum    refnum = ODDeduceRefNum(ev, file, refNumCount, refNums);
  802.     if (refNums)
  803.         ODDisposePtr(refNums);
  804.     
  805.     if (HAS_WRITE_ACCESS(permissions) && !file->IsLocked())
  806.     {
  807.         currentdraft = 
  808.             document->AcquireDraft(ev, permissions,0, currentdraft, kODPosSame, kODTrue);
  809.         currentdraft = document->CreateDraft(ev, currentdraft, kODTrue);
  810.         tempdraft = currentdraft;
  811.         tempdraft->Acquire(ev); 
  812.             // Because "The caller is responsible for properly refcounting the tempdraft."
  813.             // From DocUtils.h documentation of ODDocumentOpened.
  814.     }
  815.             
  816.     ODDocumentOpened(ev, session, refnum, document, tempdraft);
  817.     
  818.     return currentdraft;
  819. }
  820.  
  821. //------------------------------------------------------------------------------
  822. // ODOpenDraft
  823. //------------------------------------------------------------------------------
  824.  
  825. void ODOpenDraft(Environment* ev, ODSession* session, ODDraft* draft)
  826. {
  827.     WASSERT(session != kODNULL);
  828.     WASSERT(draft != kODNULL);
  829.  
  830.     if (!session)
  831.         THROW(kODErrIllegalNullInput);
  832.     if (!draft)
  833.         THROW(kODErrIllegalNullDraftInput);
  834.  
  835.     ODBoolean    windowsOpen = kODFalse;
  836.     ODWindowState* windowState = session->GetWindowState(ev);
  837.  
  838.     windowState->Internalize(ev,draft);
  839.     windowState->OpenWindows(ev, draft);
  840.     windowsOpen = (windowState->GetRootWindowCount(ev, draft)>0);
  841.  
  842.     //need this for NoPart alert 
  843.     if (session->GetDispatcher(ev)->ShouldExit(ev))
  844.         return;
  845.         
  846.     if (!windowsOpen)
  847.     {
  848.         TempODPart    rootPart = ODAcquireRootPartOfDraft(ev, draft);
  849.         rootPart->Open(ev, kODNULL);
  850.         windowState->SetDefaultWindowTitles(ev, draft);
  851.     }
  852.     session->GetLinkManager(ev)->DraftOpened(ev,draft);
  853. }
  854.  
  855. //------------------------------------------------------------------------------
  856. // ODCloseDraft
  857. //------------------------------------------------------------------------------
  858.  
  859. void ODCloseDraft(Environment* ev, ODSession* session, ODDraft* draft)
  860. {
  861.     WASSERT(session != kODNULL);
  862.     WASSERT(draft != kODNULL);
  863.  
  864.     if (!session)
  865.         THROW(kODErrIllegalNullInput);
  866.     if (!draft)
  867.         THROW(kODErrIllegalNullDraftInput);
  868.         
  869.     session->GetLinkManager(ev)->DraftClosing(ev, draft);
  870.     session->GetUndo(ev)->ClearActionHistory(ev, kODDontRespectMarks);
  871.     session->GetClipboard(ev)->DraftClosing(ev, draft);
  872.     session->GetWindowState(ev)->CloseWindows(ev, draft);
  873. }
  874.  
  875. //------------------------------------------------------------------------------
  876. // ODCloseDocument
  877. //------------------------------------------------------------------------------
  878.  
  879. ODBoolean ODCloseDocument(Environment* ev, ODSession* session, ODDocument* document)
  880. {
  881.     RETURN_IF_NULL(document, kODFalse);    // For the caller's convenience.
  882.  
  883.     ODDraft* tempDraft = ODGetTempDraftFromOpenDocument(ev, session, document);
  884.  
  885.     ODRefCntCollection*    draftsWithOpenWindows = new ODRefCntCollection(ev);
  886.  
  887.     ODWindowIterator* iter = session->GetWindowState(ev)->CreateWindowIterator(ev);
  888.     ODWindow* window = kODNULL;
  889.     while ((window = iter->Next(ev)) != kODNULL)
  890.     {
  891.         // close all windows whose draft's document = document
  892.         ODDraft* draft = ODGetDraftOfWindow(ev, window);
  893.         WASSERT(draft != kODNULL);
  894.         if (ODObjectsAreEqual(ev, document, draft->GetDocument(ev))
  895.             && !draftsWithOpenWindows->Contains(draft))
  896.             draftsWithOpenWindows->AddFirstAndAcquire(draft);
  897.     }
  898.     ODDeleteObject(iter);
  899.  
  900.     ODDraft* draft = kODNULL;
  901.     while ((draft = (ODDraft*)draftsWithOpenWindows->RemoveFirst()) != kODNULL)
  902.     {
  903.         ODCloseDraft(ev, session, draft);
  904.         draft->Release(ev); // to balance AddFirstAndAcquire above.
  905.     }
  906.  
  907.     ODDeleteObject(draftsWithOpenWindows);
  908.     if (tempDraft)
  909.     {
  910.         tempDraft->RemoveChanges(ev);
  911.         WASSERT(tempDraft->GetRefCount(ev) == 1);
  912.         tempDraft->RemoveFromDocument(ev);
  913.     }
  914.     ODDocumentClosed(ev, session, document);
  915.     
  916.     TempODWindow activeWindow = ODAcquireActiveWindow(ev, session);
  917.     return (activeWindow == kODNULL);
  918. }
  919.  
  920. //------------------------------------------------------------------------------
  921. // ODReleaseCloseWindow
  922. //------------------------------------------------------------------------------
  923.  
  924. ODBoolean ODReleaseCloseWindow(Environment* ev, ODSession* session, ODWindow* window)
  925. {
  926.     WASSERT(session != kODNULL);
  927.     WASSERT(window != kODNULL);
  928.  
  929.     if (!session)
  930.         THROW(kODErrIllegalNullInput);
  931.     if (!window)
  932.         THROW(kODErrIllegalNullInput);
  933.  
  934.     WASSERT(window->GetRefCount(ev) > 1);
  935. #if ODDebug
  936.     ODULong windowRefCount = window->GetRefCount(ev);
  937.     if (windowRefCount != 3)
  938.     {
  939.         WARN("Trying to close a window with RefCount of (%d) != 3.", windowRefCount);
  940.         WARN("…expect problems later closing the draft, document and container.-TÇ");
  941.         WARN("Solution? Make sure window is properly refcounted.");
  942.         WARN("Possible Culprit: Part::Open forgetting to release a registered window.");
  943.     }
  944. #endif
  945.     
  946.     ODBoolean wasLastRootWindow = kODFalse;
  947.     ODDraft* draft = ODGetDraftOfWindow(ev, window);
  948.     draft->Acquire(ev);    // necessary just in case closing all windows fully releases the draft
  949.     ODBoolean isOnlyDraftWindow 
  950.         = window->IsRootWindow(ev) && 
  951.         (session->GetWindowState(ev)->GetRootWindowCount(ev, draft) == 1);
  952.     if (isOnlyDraftWindow)
  953.     {
  954.         window->Release(ev);
  955.         ODCloseDraft(ev, session, draft);
  956.  
  957.         ODDocument* document = draft->GetDocument(ev);
  958.         if (!document->Exists(ev, kODNULLID, draft, kODPosFirstAbove))
  959.         {
  960.             ODReleaseObject(ev, draft); // to balance the above Acquire before calling ODCloseDocument.
  961.             wasLastRootWindow = ODCloseDocument(ev, session, document);
  962.         }
  963.     }
  964.     else
  965.     {
  966.         window->CloseAndRemove(ev);
  967.     }
  968.     ODReleaseObject(ev, draft);
  969.     return wasLastRootWindow;
  970. }
  971.  
  972. //------------------------------------------------------------------------------
  973. // ODDeleteDocument
  974. //------------------------------------------------------------------------------
  975.  
  976. ODBoolean ODDeleteDocument(Environment* ev, ODSession* session, ODDocument* document)
  977. {
  978.     WASSERT(session != kODNULL);
  979.     WASSERT(document != kODNULL);
  980.  
  981.     if (!session)
  982.         THROW(kODErrIllegalNullInput);
  983.     if (!document)
  984.         THROW(kODErrIllegalNullDocumentInput);
  985.         
  986.     TempPlatformFile    currentFile = 
  987.         GetPlatformFileFromContainer(ev, document->GetContainer(ev));                            
  988.     ODBoolean retval = ODCloseDocument(ev, session, document);
  989.     currentFile->MoveToTrash();
  990.     return retval;
  991. }
  992.  
  993. //------------------------------------------------------------------------------
  994. // ODSaveDocument
  995. //------------------------------------------------------------------------------
  996.  
  997. void ODSaveDocument(Environment* ev, ODSession* session, ODDocument* document)
  998. {
  999.     WASSERT(session != kODNULL);
  1000.     WASSERT(document != kODNULL);
  1001.  
  1002.     if (!session)
  1003.         THROW(kODErrIllegalNullInput);
  1004.     if (!document)
  1005.         THROW(kODErrIllegalNullDocumentInput);
  1006.  
  1007.     ODDraft* tempDraft = ODGetTempDraftFromOpenDocument(ev, session, document);
  1008.     if (tempDraft)
  1009.     {
  1010.         WatchCursor();
  1011.         session->GetUndo(ev)->ClearActionHistory(ev, kODDontRespectMarks);
  1012.     
  1013.         // Fix desktop information which parallels the rootpart such as:
  1014.         // filename, comments, stationery bit, etc.
  1015.         SyncPropertiesToFile(ev, session, document);
  1016.     
  1017.         TempODStorageUnit su = tempDraft->AcquireDraftProperties(ev);
  1018.         ODSURemoveProperty(ev, su, kODPropUnsavedDocument);
  1019.         
  1020.         session->GetWindowState(ev)->Externalize(ev, tempDraft);
  1021.         tempDraft->Externalize(ev);
  1022.         session->GetLinkManager(ev)->DraftSaved(ev, tempDraft);
  1023.         session->GetClipboard(ev)->DraftSaved(ev, tempDraft);
  1024.     
  1025.         tempDraft->SaveToAPrevious(ev, kODNULL);
  1026.  
  1027.         ArrowCursor();
  1028.         session->GetDispatcher(ev)->InvalidateFacetUnderMouse(ev);
  1029.     }
  1030. }
  1031.  
  1032. //------------------------------------------------------------------------------
  1033. // ODSaveACopyOfDraft
  1034. //    Saves a copy of the draft.
  1035. //------------------------------------------------------------------------------
  1036.  
  1037. void ODSaveACopyOfDraft(Environment* ev, ODSession* session, ODDraft* fromDraft, 
  1038.                         PlatformFile* destinationFile)
  1039. {
  1040.     WASSERT(session != kODNULL);
  1041.     WASSERT(fromDraft != kODNULL);
  1042.     WASSERT(destinationFile != kODNULL);
  1043.  
  1044.     if (!session)
  1045.         THROW(kODErrIllegalNullInput);
  1046.  
  1047.     if (!fromDraft)
  1048.         THROW(kODErrIllegalNullDraftInput);
  1049.  
  1050.     if (!destinationFile)
  1051.         THROW(kODErrIllegalNullInput);
  1052.         
  1053.     WatchCursor();
  1054.     if (ODDraftHasWriteAccess(ev, fromDraft) && fromDraft->ChangedFromPrev(ev))
  1055.     {
  1056.         session->GetWindowState(ev)->Externalize(ev, fromDraft);
  1057.         fromDraft->Externalize(ev);
  1058.     }
  1059.     
  1060.     TempPlatformFile currentFile = 
  1061.         GetPlatformFileFromContainer(ev, fromDraft->GetDocument(ev)->GetContainer(ev));
  1062.     TempODStorageUnit partSU = ODAcquireRootPartSUOfDraft(ev, fromDraft);
  1063.     ODPlatformType fileType = ODGetIconFilePlatformTypeFromPartSU(ev, partSU);
  1064.     destinationFile->Create(currentFile->GetPlatformCreator(),fileType,0);
  1065.     
  1066.     TempODContainer    newContainer = 
  1067.         CreateFileContainer(ev, session, &(destinationFile->GetFileSpec()));    
  1068.     TempODDocument    newDocument = newContainer->AcquireDocument(ev, kODDefaultDocument);
  1069.     newDocument->SetBaseDraftFromForeignDraft(ev, fromDraft);
  1070.     TempODDraft    newDraft = newDocument->AcquireBaseDraft(ev, kODDPExclusiveWrite);
  1071.     TempODStorageUnit su = newDraft->AcquireDraftProperties(ev);
  1072.     ODSURemoveProperty(ev, su, kODPropUnsavedDocument);
  1073.     newDraft->Externalize(ev);
  1074.  
  1075.     ArrowCursor();
  1076. }
  1077.  
  1078.  
  1079. //------------------------------------------------------------------------------
  1080. // ODRevertDocument
  1081. //------------------------------------------------------------------------------
  1082.  
  1083. void ODRevertDocument(Environment* ev, ODSession* session, ODDocument* document)
  1084. {
  1085.     WASSERT(session != kODNULL);
  1086.     WASSERT(document != kODNULL);
  1087.     if (!session)
  1088.         THROW(kODErrIllegalNullInput);
  1089.     if (!document)
  1090.         THROW(kODErrIllegalNullDocumentInput);
  1091.  
  1092.     ODDraft* tempDraft = ODGetTempDraftFromOpenDocument(ev, session, document);
  1093.     if (tempDraft)
  1094.     {
  1095.         WatchCursor();
  1096.         ODCloseDraft(ev, session, tempDraft);    
  1097.         tempDraft->RemoveChanges(ev);
  1098.         ODOpenDraft(ev, session, tempDraft);
  1099.         SyncFileToProperties(ev, session, document);
  1100.         ArrowCursor();
  1101.         session->GetDispatcher(ev)->InvalidateFacetUnderMouse(ev);
  1102.     }
  1103. }
  1104.  
  1105. //------------------------------------------------------------------------------
  1106. // ODDocumentInfo
  1107. //------------------------------------------------------------------------------
  1108.  
  1109. void ODDocumentInfo(Environment* ev, ODSession* session)
  1110. {
  1111.     WASSERT(session != kODNULL);
  1112.     if (!session)
  1113.         THROW(kODErrIllegalNullInput);
  1114.  
  1115.     ArrowCursor();
  1116.  
  1117.     ODFacet* infoFacet = kODNULL;
  1118.     ODBoolean hasWriteAccess = kODFalse;
  1119.     {
  1120.     TempODWindow window = session->GetWindowState(ev)->AcquireFrontRootWindow(ev);
  1121.     infoFacet = window->GetRootFacet(ev);
  1122.     hasWriteAccess = ODDraftHasWriteAccess(ev, ODGetDraftOfWindow(ev, window));
  1123.     }
  1124.     session->GetInfo(ev)->ShowPartFrameInfo(ev, infoFacet, hasWriteAccess);
  1125. }
  1126.  
  1127.  
  1128. //------------------------------------------------------------------------------
  1129. // ODIsTempDocument
  1130. //------------------------------------------------------------------------------
  1131.  
  1132. ODBoolean ODIsTempDocument(Environment* ev, ODSession* session, ODDocument* document)
  1133. {
  1134.     ODDraft* draft = ODGetTempDraftFromOpenDocument(ev, session, document);
  1135.     RETURN_IF_NULL(draft, kODFalse);
  1136.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  1137.     if (!su->Exists(ev, kODPropTempDocument, kODBoolean, 0))
  1138.         return kODFalse;
  1139.     return ODGetBooleanProp(ev, su, kODPropTempDocument, kODBoolean);
  1140. }
  1141.  
  1142. //------------------------------------------------------------------------------
  1143. // ODSetIsTempDocument
  1144. //------------------------------------------------------------------------------
  1145.  
  1146. void ODSetIsTempDocument(Environment* ev, ODDraft* draft, ODBoolean isTemp)
  1147. {
  1148.     if (!draft)
  1149.         return;
  1150.     TempODStorageUnit su = draft->AcquireDraftProperties(ev);
  1151.     if (isTemp)
  1152.         ODSetBooleanProp(ev, su, kODPropTempDocument, kODBoolean, isTemp);
  1153.     else
  1154.         ODSURemoveProperty(ev, su, kODPropTempDocument);
  1155. }
  1156.  
  1157. //------------------------------------------------------------------------------
  1158. // SyncFileToProperties
  1159. //------------------------------------------------------------------------------
  1160.  
  1161. void SyncFileToProperties(Environment* ev, ODSession* session, ODDocument* document)
  1162. {
  1163.     ODDraft*            tempDraft    = ODGetTempDraftFromOpenDocument(ev, session, document);
  1164.     TempODPart            rootPart    = ODAcquireRootPartOfDraft(ev, tempDraft);
  1165.     ODIText*            foo            = kODNULL;
  1166.     ODIconFamily        icons        = kODNULL;
  1167.     TempPlatformFile    file        = GetPlatformFileFromContainer(ev, document->GetContainer(ev));
  1168.     
  1169.     // filename
  1170.     foo = ODGetPOName(ev, rootPart, kODNULL);
  1171.     if (foo)
  1172.     {
  1173.         Str255    pName;
  1174.         GetITextPString(foo, pName);
  1175.         TRY
  1176.             file->Rename(pName);
  1177.         CATCH_ALL
  1178.         ENDTRY
  1179.         DisposeIText(foo);
  1180.         ODWindowState* windowState = session->GetWindowState(ev);
  1181.         windowState->SetDefaultWindowTitles(ev, tempDraft);
  1182.     }
  1183.     
  1184.     // stationery
  1185.     file->SetStationery(ODGetSUIsStationery(ev, rootPart->GetStorageUnit(ev)));
  1186.     
  1187.     // comments
  1188.     foo = ODGetPOComments(ev, rootPart, kODNULL);
  1189.     if (foo != kODNULL)
  1190.     {
  1191.         file->SetComments(foo);
  1192.         DisposeIText(foo);
  1193.     }
  1194.  
  1195.     // custom icon
  1196.     icons = ODGetPOIconFamily(ev, rootPart);
  1197.     file->SetCustomIconFamily(icons);
  1198.     if (icons)
  1199.         THROW_IF_ERROR( DisposeIconSuite(icons, kODTrue) );
  1200. }
  1201.  
  1202.  
  1203. //------------------------------------------------------------------------------
  1204. // SyncPropertiesToFile
  1205. //------------------------------------------------------------------------------
  1206.  
  1207. void SyncPropertiesToFile(Environment* ev, ODSession* session, ODDocument* document)
  1208. {
  1209.     TempODWindow        odWindow    = session->GetWindowState(ev)->AcquireFrontRootWindow(ev);
  1210.     ODFrame*            frame        = odWindow->GetRootFrame(ev);
  1211.     ODDraft*            tempDraft    = ODGetTempDraftFromOpenDocument(ev, session, document);
  1212.     TempODPart            rootPart    = ODAcquireRootPartOfDraft(ev, tempDraft);
  1213.     ODStorageUnit*        su            = ODGetSUFromPstObj(ev, (ODPart*)rootPart);
  1214.     ODIText*            foo            = kODNULL;
  1215.     ODIconFamily        icons        = kODNULL;
  1216.     TempPlatformFile    file        = GetPlatformFileFromContainer(ev, document->GetContainer(ev));
  1217.     
  1218.     // filename
  1219.     foo = file->GetName();
  1220.     if (foo)
  1221.     {
  1222.         ODSetPOName(ev, rootPart, foo);
  1223.         DisposeIText(foo);
  1224.     }
  1225.     
  1226.     // stationery
  1227.     ODSetSUIsStationery(ev, su, file->IsStationery());
  1228.  
  1229.     // comments
  1230.     //
  1231.     // this gets comments and makes sure that the file matches the property
  1232.     // we just need to make sure that the property matches the file
  1233.     foo = ODGetComments(ev, frame, kODNULL);
  1234.     if (foo != kODNULL)
  1235.     {
  1236.         ODSetPOComments(ev, rootPart, foo);
  1237.         DisposeIText(foo);
  1238.     }
  1239.  
  1240.     // custom icon
  1241.     icons = file->GetCustomIconFamily();
  1242.     ODSetPOIconFamily(ev, rootPart, icons, kODFalse);
  1243.     if (icons)
  1244.         THROW_IF_ERROR( DisposeIconSuite(icons, kODTrue) );
  1245. }
  1246.  
  1247.  
  1248.